﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Superbaby.PrettyUI.Forms;
using System.Runtime.InteropServices;

namespace FetionLite
{
    public partial class DialogForm : Form
    {
        private FetionAccount _account;
        private bool _sendSMS;
        private bool _inDialog;
        private BubbleTextPanel _lastPanel;

        [Serializable, StructLayout(LayoutKind.Sequential)]
        struct SCROLLINFO
        {
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;
        }

        private enum ScrollBarDirection
        {
            SB_HORZ = 0,
            SB_VERT = 1,
            SB_CTL = 2,
            SB_BOTH = 3
        }

        private enum ScrollInfoMask
        {
            SIF_RANGE = 0x1,
            SIF_PAGE = 0x2,
            SIF_POS = 0x4,
            SIF_DISABLENOSCROLL = 0x8,
            SIF_TRACKPOS = 0x10,
            SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
        }

        [DllImport("coredll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);

        [DllImport("coredll")]
        static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO
           lpsi, bool fRedraw);

        [return: MarshalAs(UnmanagedType.Bool)]
        [DllImport("coredll", SetLastError = true)]
        static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        public FetionAccount Account
        {
            get { return this._account; }
        }

        public DialogForm(FetionAccount account)
        {
            InitializeComponent();

            if (Fetion.Instance.IsPCUser(account.Id))
            {
                Fetion.Instance.BeginDialog(account.Id);
                _inDialog = true;
            }

            //this.chatPanel.TabStop = false;

            this._account = account;
        }

        private void ChatForm_Load(object sender, EventArgs e)
        {
            this.Text = string.Format("正在和 {0} 聊天", this._account.ShowName);

            this.chatPanel.Height = this.ClientSize.Height - this.txtSend.Height - 5;
            this.txtSend.Focus();
        }

        public delegate void AppendMessageDelegate(FetionMsg msg);
        public void SelfAppendMessage(FetionMsg msg)
        {
            //this.chatPanel.Text += string.Format("\r\n{0}：{1}", this._account.Personal.NickName, msg.PlainMessage);
            BubbleTextPanel p = new BubbleTextPanel();
            p.Font = this.Font;
            p.FillColor = Color.Pink;
            p.Left = 10;
            p.Width = this.ClientSize.Width - 20;
            if (_lastPanel != null)
                p.Top = _lastPanel.Bottom + 6;
            else
                p.Top = 10;
            p.AutoHeight = true;
            p.Text = string.Format("{0}：{1}", this._account.ShowName, msg.PlainMessage);

            this.chatPanel.Controls.Add(p);
            ScrollChatPanelDown();
            _lastPanel = p;
        }

        public void AppendMessage(FetionMsg msg)
        {
            this.BeginInvoke(new AppendMessageDelegate(SelfAppendMessage), msg);
        }

        private void miSend_Click(object sender, EventArgs e)
        {
            //this.chatPanel.Text += string.Format("\r\n我：{0}", this.txtSend.Text);

            BubbleTextPanel p = new BubbleTextPanel();
            p.Font = this.Font;
            p.FillColor = Color.LightBlue;
            p.Left = 10;
            p.Width = this.ClientSize.Width - 20;
            if (_lastPanel != null)
                p.Top = _lastPanel.Bottom + 6;
            else
                p.Top = 10;
            p.AutoHeight = true;
            p.Text = string.Format("我：{0}", this.txtSend.Text);

            this.chatPanel.Controls.Add(p);
            ScrollChatPanelDown();

            _lastPanel = p;

            if (!_sendSMS)
                Fetion.Instance.SendDialogMessage(_account.Id, this.txtSend.Text);
            else
                Fetion.Instance.SendSMSMessage(_account.Id, this.txtSend.Text);

            this.txtSend.Text = "";
            this.txtSend.Focus();
        }

        private SCROLLINFO GetChatPanelScrollInfo()
        {
            SCROLLINFO si = new SCROLLINFO();
            si.cbSize = Marshal.SizeOf(si);
            si.fMask = (int)ScrollInfoMask.SIF_RANGE + (int)ScrollInfoMask.SIF_POS;
            GetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si);

            return si;
        }

        private void ScrollChatPanelUp()
        {
            //SCROLLINFO si = new SCROLLINFO();
            //si.cbSize = Marshal.SizeOf(si);
            //si.fMask = (int)ScrollInfoMask.SIF_RANGE + (int)ScrollInfoMask.SIF_POS;
            //GetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si);

            //si.nPos = si.nPos - 20 > si.nMin ? si.nPos - 20 : si.nMin;
            //si.fMask = (int)ScrollInfoMask.SIF_POS;
            //SetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si, true);
            PostMessage(chatPanel.Handle, 0x115, new IntPtr(2), IntPtr.Zero);
        }

        private void ScrollChatPanelDown()
        {
            //SCROLLINFO si = new SCROLLINFO();
            //si.cbSize = Marshal.SizeOf(si);
            //si.fMask = (int)ScrollInfoMask.SIF_RANGE + (int)ScrollInfoMask.SIF_POS;
            //GetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si);

            //si.nPos = si.nPos + 20 < si.nMax ? si.nPos + 20 : si.nMax;
            //si.fMask = (int)ScrollInfoMask.SIF_POS;
            //SetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si, true);
            PostMessage(chatPanel.Handle, 0x115, new IntPtr(3), IntPtr.Zero);
        }

        private void ScrollChatPanelToBottom()
        {
            SCROLLINFO si = new SCROLLINFO();
            si.cbSize = Marshal.SizeOf(si);
            si.fMask = (int)ScrollInfoMask.SIF_ALL;
            GetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si);

            si.nPos = si.nMax;
            //SetScrollInfo(chatPanel.Handle, (int)ScrollBarDirection.SB_VERT, ref si, true);

            PostMessage(chatPanel.Handle, 0x115, new IntPtr(7), IntPtr.Zero);

            chatPanel.Refresh();
        }

        private void miClose_Click(object sender, EventArgs e)
        {
            if (_inDialog)
                Fetion.Instance.EndDialog(_account.Id);

            this.Close();
        }

        private void ChatForm_Activated(object sender, EventArgs e)
        {

        }

        private void txtSend_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.Up:
                    ScrollChatPanelUp();
                    break;
                case Keys.Down:
                    ScrollChatPanelDown();
                    break;
            }

        }
    }
}